library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
USE ieee.std_logic_misc.ALL;



entity arbiter IS
    GENERIC(
       num_requester      : natural := 4
    );
    PORT( 
       clk                : IN   std_logic;
       request            : IN   unsigned (num_requester-1 DOWNTO 0);
       start_schedule     : IN   std_logic;
       
       schedule_nr        : OUT   std_logic_vector (num_requester-1 DOWNTO 0);
       scheduling_done    : OUT   std_logic           
    );
end arbiter;



architecture Behavioral of arbiter is
   
   signal rrb_shiftreg : unsigned (num_requester-1 DOWNTO 0) := '1' & (num_requester-2 DOWNTO 0 => '0');

   signal schedule_nr_buffer : unsigned (num_requester-1 DOWNTO 0);
   signal scheduling_done_buffer : std_logic := '0';
    
begin
        

 
process (clk)
begin
  if rising_edge(clk) then
    
    if start_schedule='1' then
        scheduling_done_buffer <= '0';
    end if;
     
        
    if scheduling_done_buffer = '0' then 
    
       rrb_shiftreg <= rrb_shiftreg(0) & rrb_shiftreg(num_requester-1 downto 1);
       
       if xor_reduce(std_logic_vector(request))='1' then
		      schedule_nr_buffer <= request;
          scheduling_done_buffer <= '1';
       elsif (request and rrb_shiftreg)>0 then
          schedule_nr_buffer <= rrb_shiftreg;
          scheduling_done_buffer <= '1';
       end if;
                    
    end if;
    
  end if;
end process;


schedule_nr <= std_logic_vector(schedule_nr_buffer);
scheduling_done <= scheduling_done_buffer;

end Behavioral;






